package 二链表;

/**
 * @Author XuZhuHong
 * @CreateTime 2021/9/11 10:17
 * 计算器实现
 */
public class CalculatorLinkedListStackDemo {
    public static void main(String[] args) {
        String expression = "100+7+3+2*5";
        CalculatorLinkedListStack oper = new CalculatorLinkedListStack(10);
        CalculatorLinkedListStack number = new CalculatorLinkedListStack(10);
        int value;
        int num1;
        int num2;
        int operator;
        String numString = "";

        for (int i = 0; i < expression.length(); i++) {
            value = expression.substring(i, i + 1).charAt(0);
//            System.out.println((char)value+" "+value);

            //判断是否为运算符
            if (oper.isOper(value)) {
                //是运算符的操作

                //如果是空的就可以直接进入符号栈
                if (oper.isEmpty()) {
                    oper.push(value);
                } else {
                    //判断当前的运算符和栈顶的运算符优先级大小
                    //如果小于等于  就先提取出 数字栈的两个数字 和 运算符栈 顶的 运算符
                    //进行运算  然后  再把结果放入数字栈顶   再把当的运算符 放入  运算符栈
                    //如果大于就直接入栈
                    if (oper.priority(value) <= oper.priority(oper.showHead())) {
                        num1 = number.pop();
                        num2 = number.pop();
                        operator = oper.pop();
                        int cal = oper.cal(num1, num2, operator);

                        //当前的运算符  放入符号栈中
                        oper.push(value);
                        //把运算结果重新放入数字栈中
                        number.push(cal);

                    } else {
                        oper.push(value);
                    }
                }
            } else {
                //不是运算符的操作
                //直接进入数字栈
                numString = String.valueOf(expression.charAt(i));
                for (int j = i + 1; j < expression.length(); j++) {
                    if (oper.isOper(expression.charAt(j))) {
                        break;
                    }
                    numString += expression.charAt(j);
                    i++;
                }
                value = new Integer(numString);
                number.push(value); //因为是字符型 和整形相差48所以这里要减去48
            }
        }

        //把栈中所有剩下的操作符运算完
        while (true) {
            if (oper.isEmpty()) {
                break;
            } else {
                num1 = number.pop();
                num2 = number.pop();
                operator = oper.pop();
                int cal = oper.cal(num1, num2, operator);
                //把运算结果重新放入数字栈中
                number.push(cal);
            }
        }

        //最后的结果：
        System.out.println(expression + "=" + number.pop());

    }
}

class CalculatorLinkedListStack {

    private CalculatorLinkedList head;
    private int maxSize;

    public CalculatorLinkedListStack(int maxSize) {
        head = new CalculatorLinkedList(0);
        this.maxSize = maxSize;
    }

    //运算逻辑
    public int cal(int num1, int num2, int oper) {
        switch (oper) {
            case '+':
                return num2 + num1;
            case '-':
                return num2 - num1;
            case '*':
                return num2 * num1;
            case '/':
                return num2 / num1;
            default:
                return -1;
        }
    }

    //判断是否是运算符号
    public boolean isOper(int oper) {
        if (oper == '+' || oper == '-' || oper == '*' || oper == '/') {
            return true;
        }
        return false;
    }

    //判断优先级
    public int priority(int oper) {
        if (oper == '+' || oper == '-') {
            return 0;
        } else if (oper == '*' || oper == '/') {
            return 1;
        }
        return -1;
    }

    //得到最上面的元素 不出
    public int showHead() {
        if (isEmpty()) {
            throw new RuntimeException("空了");
        }
        return head.getNext().getValue();
    }


    //入栈
    public void push(int value) {
        if (isFull()) {
            System.out.println("满了");
            return;
        }

        CalculatorLinkedList culatorLinkedList = new CalculatorLinkedList(value);
        culatorLinkedList.setNext(head.getNext());
        head.setNext(culatorLinkedList);

    }

    //出栈
    public int pop() {
        if (isEmpty()) {
            throw new RuntimeException("空了");
        }
        int value = head.getNext().getValue();
        head.setNext(head.getNext().getNext());
        return value;
    }

    //遍历
    public void list() {
        if (isEmpty()) {
            System.out.println("空了");
            return;
        }

        CalculatorLinkedList temp = head.getNext();
        while (temp != null) {
            System.out.println(temp);
            temp = temp.getNext();
        }
    }

    //是否满
    public boolean isFull() {
        boolean flag = true;
        CalculatorLinkedList temp = head.getNext();
        for (int i = 0; i < maxSize; i++) {
            if (temp == null) {
                flag = false;
                break;
            }
            temp = temp.getNext();
        }
        return flag;
    }

    //是否空
    public boolean isEmpty() {
        if (head.getNext() == null) {
            return true;
        }
        return false;
    }


}


class CalculatorLinkedList {
    private int value;
    private CalculatorLinkedList next;

    public CalculatorLinkedList(int value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "LinkedList{" +
                "value=" + value +
                '}';
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public CalculatorLinkedList getNext() {
        return next;
    }

    public void setNext(CalculatorLinkedList next) {
        this.next = next;
    }
}
